/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.geotools.tutorial;

import com.vividsolutions.jts.geom.Envelope;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.MultiLineString;
import com.vividsolutions.jts.geom.Point;
import com.vividsolutions.jts.index.SpatialIndex;
import com.vividsolutions.jts.index.strtree.STRtree;
import com.vividsolutions.jts.linearref.LocationIndexedLine;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.data.simple.SimpleFeatureSource;
import org.geotools.feature.FeatureIterator;
import org.geotools.graph.build.feature.FeatureGraphGenerator;
import org.geotools.graph.build.line.LineStringGraphGenerator;
import org.geotools.graph.path.DijkstraShortestPathFinder;
import org.geotools.graph.path.Path;
import org.geotools.graph.structure.Edge;
import org.geotools.graph.structure.Graph;
import org.geotools.graph.structure.Node;
import org.geotools.graph.structure.basic.BasicDirectedNode;
import org.geotools.graph.structure.basic.BasicNode;
import org.geotools.graph.traverse.standard.DijkstraIterator;
import org.geotools.util.NullProgressListener;
import org.opengis.feature.Feature;
import org.opengis.feature.FeatureVisitor;
import org.opengis.feature.simple.SimpleFeature;

import org.geotools.graph.traverse.standard.DijkstraIterator.EdgeWeighter;

/**
 *
 * @author oleg
 */
public class MyGraph {

    SimpleFeatureSource featureSource;

    public MyGraph(SimpleFeatureSource featureSource) {
        this.featureSource = featureSource;
        
    }

    public void function1(Point p1, Point p2) {
        try {
            // get a feature collection somehow
            SimpleFeatureCollection fCollection = featureSource.getFeatures();
            //create a linear graph generate
            LineStringGraphGenerator lineStringGen = new LineStringGraphGenerator();
            //wrap it in a feature graph generator
            FeatureGraphGenerator featureGen = new FeatureGraphGenerator(lineStringGen);
            //throw all the features into the graph generator
            FeatureIterator iter = fCollection.features();
            try {
                while (iter.hasNext()) {
                    Feature feature = iter.next();
                    featureGen.add(feature);
                }
            } finally {
                iter.close();
            }
            Graph graph = (Graph) featureGen.getGraph();
            //find a source node (usually your user chooses one)
            Collection nodes = graph.getNodes();
            
            Collection edges = graph.getEdges();
            Object[] toArray1 = edges.toArray();
            Edge e=(Edge) toArray1[(int)(Math.random()*toArray1.length)];
            Node start = e.getNodeA();
            Node finish = e.getNodeB();
            



// create a strategy for weighting edges in the graph
// in this case we are using geometry length
            DijkstraIterator.EdgeWeighter weighter = new DijkstraIterator.EdgeWeighter() {

                public double getWeight(Edge e) {
                    SimpleFeature feature = (SimpleFeature) e.getObject();
                    Geometry geometry = (Geometry) feature.getDefaultGeometry();
                    return geometry.getLength();
                }
            };

// Create GraphWalker - in this case DijkstraShortestPathFinder
            DijkstraShortestPathFinder pf = new DijkstraShortestPathFinder(graph, start, weighter);
            pf.calculate();
            Path path2 = pf.getPath(finish);
            
//find some destinations to calculate paths to
            List<Node> destinations = new ArrayList<Node>();
            destinations.add(finish);

//calculate the paths
            for (Iterator d = destinations.iterator(); d.hasNext();) {
                Node destination = (Node) d.next();
                Path path = pf.getPath(destination);
                System.out.println(""+path.size());
                //do something with the path
            }
        } catch (IOException ex) {
            Logger.getLogger(MyGraph.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    private void function() throws IOException {
        final SpatialIndex index = new STRtree();

        // get a feature collection somehow
        SimpleFeatureCollection fCollection = featureSource.getFeatures();
        FeatureVisitor featureVisitor = new FeatureVisitor() {

            public void visit(Feature feature) {
                SimpleFeature simpleFeature = (SimpleFeature) feature;
                Geometry geom = (MultiLineString) simpleFeature.getDefaultGeometry();
                Envelope bounds = geom.getEnvelopeInternal();
                if (bounds.isNull()) {
                    return; // must be empty geometry?
                }
                index.insert(bounds, new LocationIndexedLine(geom));
            }
        };
        fCollection.accepts(featureVisitor, new NullProgressListener());

    }
}
